const { declare } = require('@babel/helper-plugin-utils');
const importModule = require("@babel/helper-module-imports")

const autoTrackPlugin = declare((api, options, dirname) => {
  api.assertVersion(7);
  return {
    visitor: {
      // 1.判断引入包
      Program: {
        enter(path, state) {
          // path.traverse来遍历ImportDeclaration。目的：判断当前文件是否引入了options.trackerPath指定的包
          path.traverse({
            ImportDeclaration (curPath) {
              // 获取引入包的名称
                const requirePath = curPath.get('source').node.value;
                if (requirePath === options.trackerPath) {
                  // 如果引入了 trackerPath 指定的包，会执行path.stop，跳过引入(path.stop())
                    const specifierPath = curPath.get('specifiers.0');
                    if (specifierPath.isImportSpecifier()) {
                        state.trackerImportId = specifierPath.toString();
                    } else if(specifierPath.isImportNamespaceSpecifier()) {
                        state.trackerImportId = specifierPath.get('local').toString();
                    }
                    path.stop();
                }
            }
          });
          if (!state.trackerImportId) {
            // 如果没有引入，这里主动引入
              state.trackerImportId  = importModule.addDefault(path, 'tracker',{
                  nameHint: path.scope.generateUid('tracker')
              }).name;
              // 这个是执行的函数的AST
              state.trackerAST = api.template.statement(`${state.trackerImportId}()`)();
          }
        }
      },
      // 在函数中添加方法
      'ClassMethod|ArrowFunctionExpression|FunctionExpression|FunctionDeclaration'(path, state) {
        const bodyPath = path.get("body");
        if (bodyPath.isBlockStatement()) {
          // 如果有body，在body添加就可以。
          bodyPath.node.body.unshift(state.trackerAST)
        } else {
          // 没有body，如 const c = () => 'ccc';
          const ast = api.template.statement(`{${state.trackerImportId}();return PREV_BODY;}`)({PREV_BODY: bodyPath.node});
          bodyPath.replaceWith(ast);
        }
      }
    }
  }
});

module.exports = autoTrackPlugin;